use crate::core::types::Shortcut;
use crate::system::icons::{extract_icon_as_base64, get_fallback_icon};
use walkdir::WalkDir;
use tokio::task;
use log::{debug, info, error, warn};
use std::fs;
use std::time::UNIX_EPOCH;
use std::path::Path;

/// 获取当前应用程序的可执行文件路径
/// 
/// # 返回值
/// * `Option<String>` - 成功返回当前应用程序路径，失败返回None
fn get_current_exe_path() -> Option<String> {
    match std::env::current_exe() {
        Ok(path) => {
            let exe_path = path.to_string_lossy().to_string();
            debug!("当前应用程序路径: {}", exe_path);
            Some(exe_path)
        }
        Err(e) => {
            warn!("无法获取当前应用程序路径: {}", e);
            None
        }
    }
}

/// 检查快捷方式是否指向当前应用程序
/// 
/// # 参数
/// * `shortcut_path` - 快捷方式文件路径
/// * `current_exe_path` - 当前应用程序路径
/// 
/// # 返回值
/// * `bool` - 如果快捷方式指向当前应用程序返回true，否则返回false
#[cfg(target_os = "windows")]
fn is_shortcut_to_current_app(shortcut_path: &str, current_exe_path: &str) -> bool {
    use crate::system::icons::resolve_shortcut_info;
    
    // 只检查.lnk文件
    if !shortcut_path.to_lowercase().ends_with(".lnk") {
        // 对于.exe文件，直接比较路径
        if shortcut_path.to_lowercase().ends_with(".exe") {
            let shortcut_canonical = Path::new(shortcut_path)
                .canonicalize()
                .map(|p| p.to_string_lossy().to_lowercase())
                .unwrap_or_else(|_| shortcut_path.to_lowercase());
            let current_canonical = Path::new(current_exe_path)
                .canonicalize()
                .map(|p| p.to_string_lossy().to_lowercase())
                .unwrap_or_else(|_| current_exe_path.to_lowercase());
            return shortcut_canonical == current_canonical;
        }
        return false;
    }
    
    // 解析快捷方式信息
    if let Some(info) = resolve_shortcut_info(shortcut_path) {
        // 规范化路径进行比较
        let target_canonical = Path::new(&info.target_path)
            .canonicalize()
            .map(|p| p.to_string_lossy().to_lowercase())
            .unwrap_or_else(|_| info.target_path.to_lowercase());
        let current_canonical = Path::new(current_exe_path)
            .canonicalize()
            .map(|p| p.to_string_lossy().to_lowercase())
            .unwrap_or_else(|_| current_exe_path.to_lowercase());
        
        let is_same = target_canonical == current_canonical;
        if is_same {
            debug!("检测到指向当前应用的快捷方式: {} -> {}", shortcut_path, info.target_path);
        }
        return is_same;
    }
    
    false
}

#[cfg(not(target_os = "windows"))]
fn is_shortcut_to_current_app(_shortcut_path: &str, _current_exe_path: &str) -> bool {
    // 非Windows系统暂不实现
    false
}

/// 获取桌面快捷方式
/// 扫描用户桌面和公共桌面目录，获取所有可用的快捷方式
/// 自动排除指向当前应用程序的快捷方式
/// 使用异步并行处理提高性能
#[tauri::command]
pub async fn get_desktop_shortcuts() -> Result<Vec<Shortcut>, String> {
    let mut shortcuts = Vec::new();
    
    // 获取当前应用程序路径，用于排除自身
    let current_exe_path = get_current_exe_path();
    if let Some(ref path) = current_exe_path {
        info!("当前应用程序路径: {}", path);
    }
    
    // 定义要扫描的桌面路径列表
    let mut desktop_paths = Vec::new();
    
    // 添加用户桌面路径
    if let Some(user_desktop) = dirs::desktop_dir() {
        desktop_paths.push(user_desktop);
        debug!("添加用户桌面路径: {:?}", desktop_paths.last().unwrap());
    }
    
    // 添加公共桌面路径 (Windows)
    #[cfg(target_os = "windows")]
    {
        let public_desktop = Path::new("C:\\Users\\Public\\Desktop");
        if public_desktop.exists() {
            desktop_paths.push(public_desktop.to_path_buf());
            debug!("添加公共桌面路径: {:?}", public_desktop);
        }
    }
    
    if desktop_paths.is_empty() {
        return Err("无法获取任何桌面路径".to_string());
    }
    
    // 收集所有需要处理的文件路径
    let mut file_paths = Vec::new();
    
    for desktop_path in desktop_paths {
        debug!("扫描桌面目录: {:?}", desktop_path);
        
        for entry in WalkDir::new(&desktop_path)
            .max_depth(1)
            .into_iter()
            .filter_map(|e| e.ok())
        {
            let path = entry.path();
            if path.is_file() {
                if let Some(extension) = path.extension() {
                    let ext = extension.to_string_lossy().to_lowercase();
                    if ext == "lnk" || ext == "exe" || ext == "url" {
                        if let Some(name) = path.file_stem() {
                            let shortcut_name = name.to_string_lossy().to_string();
                            let file_path = path.to_string_lossy().to_string();
                            
                            // 检查是否指向当前应用程序，如果是则跳过
                            if let Some(ref current_exe) = current_exe_path {
                                if is_shortcut_to_current_app(&file_path, current_exe) {
                                    debug!("跳过指向当前应用的快捷方式: {}", file_path);
                                    continue;
                                }
                            }
                            
                            // 获取文件创建时间
                            let created_time = match fs::metadata(path) {
                                Ok(metadata) => {
                                    match metadata.created() {
                                        Ok(time) => {
                                            match time.duration_since(UNIX_EPOCH) {
                                                Ok(duration) => duration.as_secs(),
                                                Err(_) => 0,
                                            }
                                        },
                                        Err(_) => 0,
                                    }
                                },
                                Err(_) => 0,
                            };
                            
                            file_paths.push((shortcut_name, file_path, created_time));
                        }
                    }
                }
            }
        }
    }
    
    info!("找到 {} 个文件，开始并行处理图标", file_paths.len());
    
    // 使用并行任务处理图标提取
    let mut tasks = Vec::new();
    
    for (name, path, created_time) in file_paths {
        let task = task::spawn_blocking(move || {
            debug!("开始处理: {}", name);
            
            // 尝试获取真实图标，如果失败则使用后备图标
            let icon = extract_icon_as_base64(&path)
                .or_else(|| get_fallback_icon(&path));
            
            let shortcut = Shortcut {
                name: name.clone(),
                path: path.clone(),
                icon,
                created_time,
            };
            
            debug!("完成处理: {} -> {} (创建时间: {})", shortcut.name, shortcut.path, created_time);
            shortcut
        });
        tasks.push(task);
    }
    
    // 等待所有任务完成
    debug!("等待所有图标处理任务完成...");
    for task in tasks {
        match task.await {
            Ok(shortcut) => {
                // 检查是否已存在同名快捷方式（避免重复）
                if !shortcuts.iter().any(|s: &Shortcut| s.name == shortcut.name) {
                    shortcuts.push(shortcut);
                }
            }
            Err(e) => {
                error!("任务执行失败: {}", e);
            }
        }
    }
    
    // 按创建时间排序，最新的排在前面
    shortcuts.sort_by(|a, b| b.created_time.cmp(&a.created_time));
    
    info!("总共找到 {} 个快捷方式，已按创建时间排序", shortcuts.len());
    Ok(shortcuts)
}

/// 启动快捷方式
/// 在 Windows 系统上隐藏控制台窗口，避免弹出黑色命令行窗口
/// 
/// # Arguments
/// * `shortcut_path` - 要启动的快捷方式路径
/// 
/// # Returns
/// * `Ok(())` - 启动成功
/// * `Err(String)` - 启动失败，包含错误信息
#[tauri::command]
pub fn launch_shortcut(shortcut_path: String) -> Result<(), String> {
    info!("启动快捷方式: {}", shortcut_path);
    
    #[cfg(target_os = "windows")]
    {
        use std::process::Command;
        use std::os::windows::process::CommandExt;
        
        // 使用 CREATE_NO_WINDOW 标志隐藏控制台窗口
        const CREATE_NO_WINDOW: u32 = 0x08000000;
        
        Command::new("cmd")
            .args(["/C", "start", "", &shortcut_path])
            .creation_flags(CREATE_NO_WINDOW)
            .spawn()
            .map_err(|e| {
                error!("启动快捷方式失败: {}", e);
                format!("启动失败: {}", e)
            })?;
            
        debug!("快捷方式启动命令已执行");
    }
    
    #[cfg(not(target_os = "windows"))]
    {
        use std::process::Command;
        Command::new("xdg-open")
            .arg(&shortcut_path)
            .spawn()
            .map_err(|e| {
                error!("启动快捷方式失败: {}", e);
                format!("启动失败: {}", e)
            })?;
            
        debug!("快捷方式启动命令已执行");
    }
    
    Ok(())
}